#  Copyright (c) 1997-2011
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Darmstadt, Germany)
#  http://www.polymake.de
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the
#  Free Software Foundation; either version 2, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#-------------------------------------------------------------------------------
#  $Project: polymake $$Id: set_types 10341 2011-09-23 13:42:07Z paffenho $


declare property_type Set<Element=Int> : c++ (include => ["polymake/Set.h"], operators => '@sets @compare') {

   method contains {
      my ($self, $key)=@_;
      exists $self->{$key};
   }

   user_method size() : c++;
}

# @category Set operations

user_function incl(Set,Set) : c++ (include => ["polymake/Set.h"]);


# @category Set operations

user_function range(Int,Int) : c++ (include => ["polymake/Set.h"]) {
   if ($_[0] > $_[1]) {
      croak( "invalid range: lower limit > upper limit" );
   }
   &{pop(@_)};
}

# @category Set operations

user_function sequence(Int,Int) : c++ (include => ["polymake/Set.h"]) {
   if ($_[0]<0) {
      croak( "invalid sequence: negative size" );
   }
   &{pop(@_)};
}

function permuted(Set, *) : c++;

function permuted_inv(Set, *) : c++;

# @category Set operations
user_function select_subset(*:wary,*) : c++ (name => 'select', include => ["polymake/IndexedSubset.h"]);

# @category Set operations
user_function scalar2set(*) : c++ (include => ["polymake/Set.h"]);

declare property_type PowerSet<Element=Int> : Set<Set<Element>> : c++ (include => ["polymake/PowerSet.h"]);

function permuted(PowerSet, *) : c++;

function permuted_inv(PowerSet, *) : c++;



# allow to write ~[0,1,2] in contexts where a Set<Int> is expected
function _construct_set($) : subst_const_op( ~ ) {
   if ($#{$_[0]} > 0) {
      new Set($_[0])
   } else {
      scalar2set(@{$_[0]});
   }
}

 declare property_type FacetList : c++ (include => ["polymake/FacetList.h"]) {
   
   user_method insertMax(Set) : non_const : c++;

   user_method insertMin(Set) : non_const : c++;

   user_method size() : c++;

}

##################################################################################

declare property_type NonSymmetric : c++ (special => 'NonSymmetric', include => ["polymake/IncidenceMatrix.h"]);

declare property_type Symmetric : c++ (special => 'Symmetric', include => ["polymake/IncidenceMatrix.h"]);

declare property_type IncidenceMatrix<Sym=NonSymmetric> : c++ \
   (include => ["polymake/IncidenceMatrix.h"], operators => '@sets:wary |:wary |=:wary /:wary /=:wary @compare:wary') {

   method construct(*,Int) : c++;

   method construct(Int,Int) : c++;

   user_method rows() : c++;

   user_method cols() : c++;

   user_method row($) : lvalue_opt : wary : c++;

   user_method col($) : lvalue_opt : wary : c++;

   user_method minor(*,*) : lvalue_opt : wary : c++;

   method operator($,$) : lvalue_opt : wary : c++;

   user_method squeeze() : non_const : void : c++;

   user_method squeeze_rows() : non_const : void : c++;

   user_method squeeze_cols() : non_const : void : c++;
}

user_function rows(IncidenceMatrix) : c++;

user_function cols(IncidenceMatrix) : c++;

function permuted_rows(IncidenceMatrix *) : c++;

function permuted_inv_rows(IncidenceMatrix *) : c++;

function permuted_cols(IncidenceMatrix *) : c++;

function permuted_inv_cols(IncidenceMatrix *) : c++;


# @category Linear Algebra

user_function transpose(IncidenceMatrix) : c++ (name => 'T');


##################################################################################

declare property_type Map<Key,Value> : c++ (include => ["polymake/Map.h"], operators => '@string') {

   method equal {
      my ($self, $m1, $m2)=@_;
      return 0 unless keys(%$m1) == keys(%$m2);
      my ($pk, $pv)=@{$self->param};
      while (my ($k1, $v1, $k2, $v2)=(each(%$m1), each(%$m2))) {
         return 0 unless $pk->equal->($k1,$k2) && $pv->equal->($v1,$v2);
      }
      1
   }
}

##################################################################################

declare property_type HashSet<Element> : c++ (name => 'hash_set', include => ["polymake/hash_set"], operators => '+= -= ^=');

declare property_type HashMap<Key,Value> : c++ (name => 'hash_map', include => ["polymake/hash_map"]);


# Local Variables:
# mode: perl
# cperl-indent-level: 3
# indent-tabs-mode:nil
# End:
